#ifndef _THREAD_POOL_H_
#define _THREAD_POOL_H_

#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <functional>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <unistd.h>
#include <signal.h>

class ThreadUnit {
public:
    using Fun = std::function<void(void *arg)>;
    struct Task {
        Fun fun;
        void *arg;
    };

    ThreadUnit(const std::string &name);
    virtual ~ThreadUnit();

    void AddTask(Task task);
    void Loop();

    size_t GetTaskNum();
    const std::string &GetThreadName();

private:
    std::atomic<bool> m_thread_is_running;
    std::mutex m_mutex;
    std::condition_variable m_cond;
    std::queue<Task> m_task;
    std::thread m_thread;
    std::string m_name;
};

class ThreadPool {
public:
    explicit ThreadPool(size_t num);
    virtual ~ThreadPool();

    size_t SelectThread();
    void SubmitTask(ThreadUnit::Task task);

private:
    size_t m_thread_num;
    std::atomic<bool> m_thread_is_running;
    std::vector<ThreadUnit *> m_thread_unit;
};

#endif  // endif _THREAD_POOL_H_
